<?php

if(PARCL_EXEC !== 1) {
    die('<h1>Incorrect Access</h1>You cannot access this file directly.<br/>' .
         'If you got this error message by clicking a link on the site,' .
         'please notify the webmaster as soon as possible.');
}

/**
 * Purpose     : Convert arrays to XML document strings.
 * Description : By using a recursive function, this driver is converting multi-dimensional
                 arrays to XML documents.
 * - Construct -
 * Not Defined.
 */

class XMLDriver {

    /**
     * Input       : $obj: The array or ArrayObject that needs converting.
     * Output      : $xmlString: An XML document representation of the array it converted.
     * Description : This function calls upon the recursive function walker() to
                     recursively convert the array to an XML document.
     * Errors      : Throws an error if it arrays another data type than arrays
                     and also if the array have more than one element at bottom level.
     * Assumptions : None.
     * Dev Notes   : A well-working function for its purpose.
     */

    public function Generate($obj) {
        if(!is_array($obj)) {
            throw new GeneralException('Non-supported object passed to the ' . __CLASS__
                                    , getException::XML);
        }
        $xml = new DomDocument('1.0', 'UTF-8');
        $keys = array_keys($obj);
        if(count($keys) == 1) {
            $root = $xml->createElement($keys[0]);
            $root = $xml->appendChild($root);
            $docArray = array($xml, $root);
            $object = $obj[$keys[0]];
            array_walk($object, array($this, 'walker'), $docArray);
        }
        else {
            throw new GeneralException('Errornously formed object passed to the ' . __CLASS__
                                    , GeneralException::XML);
        }
        $xmlString = $xml->saveXML();
        return $xmlString;
    }

    /**
     * Input       : $value: The value of the current position in the array.
                     $key: The key of the current position in the array.
                     $docArray: Passing both the DomDocument instance and the
                     current XML element by reference to the walker.
     * Output      : No direct output.
     * Description : This function renames all numeric keys to row with an attribute
                     'id' set to the number the numeric key was. Other than that,
                     it's pretty much like any other recursive function, if it
                     finds another array to walk over while walking over one, he
                     starts walking over that too.
     * Errors      : None.
     * Assumptions : That $value and $key is assigned to what they are supposed to,
                     also that $docArray has its values in the specified order.
     * Dev Notes   : Walker, Texas Ranger. What can I say? Chuck Norris is stone
                     cold and always ready to round-house kick ass.
     */

    private function walker($value, $key, &$docArray) {
        $xml = $docArray[0];
        $elem = $docArray[1];
        if(is_numeric($key)) {
            $child = $xml->createElement('row');
            $child = $elem->appendChild($child);
            $child->setAttribute('id', $key);
        }
        else {
            $child = $xml->createElement($key);
            $child = $elem->appendChild($child);
        }
        if(is_array($value) || is_object($value)) {
            array_walk($value, array($this, 'walker'), array( $xml, $child));
        }
        else {
            $info = $xml->createCDATASection($value);
            $info = $child->appendChild($info);
        }
    }
	
    public function FileReader($xmlFile) {
        if(file_exists($xmlFile)) {
            $object = simplexml_load_file($xmlFile);
            return $object;
        }
        else {
            throw new GeneralException('File "' . $xmlFile . '" does not exist!',
                                    GeneralException::FILE_NOT_FOUND);
        }
    }
}